/****************************************************************************
**
** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the demonstration applications of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia.  For licensing terms and
** conditions see http://qt.digia.com/licensing.  For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Digia gives you certain additional
** rights.  These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU General Public License version 3.0 requirements will be
** met: http://www.gnu.org/copyleft/gpl.html.
**
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "QxColors.hpp"

#ifndef QT_NO_OPENGL
#include <QGLWidget>
#endif
//#define QT_NO_OPENGL

// QxColors:
QColor QxColors::sceneBg1( QColor(91, 91, 91) );
QColor QxColors::sceneBg1Line( QColor(114, 108, 104) );
QColor QxColors::sceneBg2( QColor(0, 0, 0) );
QColor QxColors::sceneLine( 255, 255, 255 );
QColor QxColors::paperBg( QColor(100, 100, 100) );
QColor QxColors::menuTextFg( QColor(255, 0, 0) );
QColor QxColors::buttonBgLow( QColor(255, 255, 255, 90) );
QColor QxColors::buttonBgHigh( QColor(255, 255, 255, 20) );
QColor QxColors::buttonText( QColor(255, 255, 255) );
QColor QxColors::tt_green( QColor(166, 206, 57) );
QColor QxColors::fadeOut( QColor(206, 246, 117, 0) );
QColor QxColors::heading( QColor(190,230,80) );
QString QxColors::contentColor( "<font color='#eeeeee'>" );
QString QxColors::glVersion( "Not detected!" );

// Guides:
int QxColors::stageStartY         = 8;
int QxColors::stageHeight         = 536;
int QxColors::stageStartX         = 8;
int QxColors::stageWidth          = 785;
int QxColors::contentStartY       = 22;
int QxColors::contentHeight       = 510;

// Properties:
bool QxColors::openGlRendering    = false;
bool QxColors::softwareRendering  = false;
bool QxColors::openGlAvailable    = true;
bool QxColors::xRenderPresent     = true;

bool QxColors::noTicker           = false;
bool QxColors::noRescale          = false;
bool QxColors::noAnimations       = false;
bool QxColors::noBlending         = false;
bool QxColors::noScreenSync       = false;
bool QxColors::fullscreen         = false;
bool QxColors::usePixmaps         = false;
bool QxColors::useLoop            = false;
bool QxColors::showBoundingRect   = false;
bool QxColors::showFps            = false;
bool QxColors::noAdapt            = false;
bool QxColors::noWindowMask       = true;
bool QxColors::useButtonBalls     = false;
bool QxColors::useEightBitPalette = false;
bool QxColors::noTimerUpdate      = false;
bool QxColors::noTickerMorph      = false;
bool QxColors::adapted            = false;
bool QxColors::verbose            = false;
bool QxColors::pause              = true;
int QxColors::fps                 = 60;
int QxColors::menuCount           = 18;
float QxColors::animSpeed         = 1.0;
float QxColors::animSpeedButtons  = 1.0;
float QxColors::benchmarkFps      = -1;
int QxColors::tickerLetterCount   = 80;
float QxColors::tickerMoveSpeed   = 0.4f;
float QxColors::tickerMorphSpeed  = 2.5f;
QString QxColors::tickerText      = ".EROM ETAERC .SSEL EDOC";
QString QxColors::rootMenuName    = "Qt Examples and Demos";

QFont QxColors::contentFont()
{
  QFont font;
  font.setStyleStrategy( QFont::PreferAntialias );
#if defined( Q_OS_MAC )
  font.setPixelSize( 14 );
  font.setFamily( "Arial" );
#else
  font.setPixelSize( 13 );
  font.setFamily( "Verdana" );
#endif
  return font;
}

QFont QxColors::headingFont()
{
  QFont font;
  font.setStyleStrategy( QFont::PreferAntialias );
  font.setPixelSize( 23 );
  font.setBold( true );
  font.setFamily( "Verdana" );
  return font;
}

QFont QxColors::buttonFont()
{
  QFont font;
  font.setStyleStrategy( QFont::PreferAntialias );
#if 0//defined(Q_OS_MAC)
  font.setPixelSize( 11 );
  font.setFamily( "Silom" );
#else
  font.setPixelSize( 11 );
  font.setFamily( "Verdana" );
#endif
  return font;
}

QFont QxColors::tickerFont()
{
  QFont font;
  font.setStyleStrategy( QFont::PreferAntialias );
#if defined( Q_OS_MAC )
  font.setPixelSize( 11 );
  font.setBold( true );
  font.setFamily( "Arial" );
#else
  font.setPixelSize( 10 );
  font.setBold( true );
  font.setFamily( "sans serif" );
#endif
  return font;
}

float parseFloat( const QString& argument, const QString& name )
{
  if( name.length() == argument.length() ){
    QMessageBox::warning( 0,
                          "Arguments",
                          QString( "No argument number found for " )+name+". Remember to put name and value adjacent! (e.g. -fps100)" );
    exit( 0 );
  }
  float value = argument.mid( name.length() ).toFloat();
  return value;
}

QString parseText( const QString& argument, const QString& name )
{
  if( name.length() == argument.length() ) {
    QMessageBox::warning( 0,
                          "Arguments",
                          QString( "No argument number found for " ) + name + ". Remember to put name and value adjacent! (e.g. -fps100)" );
    exit( 0 );
  }
  QString value = argument.mid( name.length() );
  return value;
}

void QxColors::parseArgs( int argc, char* argv[] )
{
  // some arguments should be processed before
  // others. Handle them now:
  for( int i = 1; i < argc; ++i ) {
    QString s( argv[i] );
    if( s == "-verbose" ) {
      QxColors::verbose = true;
    }
  }

  QxColors::detectSystemResources();

  // Handle the rest of the arguments. They may
  // override attributes already set:
  for( int i = 1; i < argc; ++i ) {
    QString s( argv[i] );
    if( s == "-opengl" ) {
      QxColors::openGlRendering = true;
    } else if( s == "-software" ) {
      QxColors::softwareRendering = true;
    } else if( s == "-no-opengl" ) {// support old style
      QxColors::softwareRendering = true;
    } else if( s == "-no-ticker" ) {// support old style
      QxColors::noTicker = true;
    } else if( s.startsWith( "-ticker" ) ) {
      QxColors::noTicker = !bool( parseFloat( s, "-ticker" ) );
    } else if( s == "-no-animations" ) {
      QxColors::noAnimations = true; // support old style
    } else if( s.startsWith( "-animations" ) ) {
      QxColors::noAnimations = !bool( parseFloat( s, "-animations" ) );
    } else if( s == "-no-adapt" ) {
      QxColors::noAdapt = true;
    } else if( s == "-low" ) {
      QxColors::setLowSettings();
    } else if( s == "-no-rescale" ) {
      QxColors::noRescale = true;
    } else if( s == "-use-pixmaps" ) {
      QxColors::usePixmaps = true;
    } else if( s == "-fullscreen" ) {
      QxColors::fullscreen = true;
    } else if( s == "-show-br" ) {
      QxColors::showBoundingRect = true;
    } else if( s == "-show-fps" ) {
      QxColors::showFps = true;
    } else if( s == "-no-blending" ) {
      QxColors::noBlending = true;
    } else if( s == "-no-sync" ) {
      QxColors::noScreenSync = true;
    } else if( s.startsWith( "-menu" ) ) {
      QxColors::menuCount = int(parseFloat( s, "-menu" ));
    } else if( s.startsWith( "-use-timer-update" ) ) {
      QxColors::noTimerUpdate = !bool(parseFloat( s, "-use-timer-update" ));
    } else if( s.startsWith( "-pause" ) ) {
      QxColors::pause = bool(parseFloat(s, "-pause"));
    } else if( s == "-no-ticker-morph" ) {
      QxColors::noTickerMorph = true;
    } else if( s == "-use-window-mask" ) {
      QxColors::noWindowMask = false;
    } else if( s == "-use-loop" ) {
      QxColors::useLoop = true;
    } else if( s == "-use-8bit" ) {
      QxColors::useEightBitPalette = true;
    } else if( s.startsWith( "-8bit" ) ) {
      QxColors::useEightBitPalette = bool(parseFloat( s, "-8bit" ));
    } else if( s == "-use-balls" ) {
      QxColors::useButtonBalls = true;
    } else if( s.startsWith( "-ticker-letters" ) ) {
      QxColors::tickerLetterCount = int(parseFloat( s, "-ticker-letters" ));
    } else if( s.startsWith( "-ticker-text" ) ) {
      QxColors::tickerText = parseText( s, "-ticker-text" );
    } else if( s.startsWith( "-ticker-speed" ) ) {
      QxColors::tickerMoveSpeed = parseFloat( s, "-ticker-speed" );
    } else if( s.startsWith( "-ticker-morph-speed" ) ) {
      QxColors::tickerMorphSpeed = parseFloat( s, "-ticker-morph-speed" );
    } else if( s.startsWith( "-animation-speed" ) ) {
      QxColors::animSpeed = parseFloat( s, "-animation-speed" );
    } else if( s.startsWith( "-fps" ) ) {
      QxColors::fps = int(parseFloat(s, "-fps"));
    } else if( s.startsWith( "-h" ) || s.startsWith( "-help" ) ) {
      QMessageBox::warning( 0,
                            "Arguments",
                            QString( "Usage: qtdemo [-verbose] [-no-adapt] [-opengl] [-software] [-fullscreen] [-ticker[0|1]] " )
                            + "[-animations[0|1]] [-no-blending] [-no-sync] [-use-timer-update[0|1]] [-pause[0|1]]  "
                            + "[-use-window-mask] [-no-rescale] "
                            + "[-use-pixmaps] [-show-fps] [-show-br] [-8bit[0|1]] [-menu<int>] [-use-loop] [-use-balls] "
                            + "[-animation-speed<float>] [-fps<int>] "
                            + "[-low] [-ticker-letters<int>] [-ticker-speed<float>] [-no-ticker-morph] "
                            + "[-ticker-morph-speed<float>] [-ticker-text<string>]" );
      exit( 0 );
    } else if( s == "-verbose" ) {
      // this option was already handled above
    } else {
      QMessageBox::warning( 0, "QxDemo", QString( "Unrecognized argument:\n" ) + s );
      exit( 0 );
    }
  }

  QxColors::postConfigure();
}

void QxColors::setLowSettings()
{
  QxColors::openGlRendering   = false;
  QxColors::softwareRendering = true;
  QxColors::noTicker          = true;
  QxColors::noTimerUpdate     = true;
  QxColors::fps               = 30;
  QxColors::usePixmaps        = true;
  QxColors::noAnimations      = true;
  QxColors::noBlending        = true;
}

void QxColors::detectSystemResources()
{
#ifndef QT_NO_OPENGL
  if( QGLFormat::openGLVersionFlags() & QGLFormat::OpenGL_Version_2_0 ) {
    QxColors::glVersion = "2.0 or higher";
  } else if( QGLFormat::openGLVersionFlags() & QGLFormat::OpenGL_Version_1_5 ) {
    QxColors::glVersion = "1.5";
  } else if( QGLFormat::openGLVersionFlags() & QGLFormat::OpenGL_Version_1_4 ) {
    QxColors::glVersion = "1.4";
  } else if( QGLFormat::openGLVersionFlags() & QGLFormat::OpenGL_Version_1_3 ) {
    QxColors::glVersion = "1.3 or lower";
  }

  if( QxColors::verbose ) {
    qDebug() << "- OpenGL version:" << QxColors::glVersion;
  }

  QGLWidget glw;
  if( !QGLFormat::hasOpenGL()
      || !glw.format().directRendering()
      || !(QGLFormat::openGLVersionFlags() & QGLFormat::OpenGL_Version_1_5)
      || glw.depth() < 24
      )
#else
  if( QxColors::verbose ) {
    qDebug() << "- OpenGL not supported by current build of Qt";
  }
#endif
  {
    QxColors::openGlAvailable = false;
    if( QxColors::verbose )
      qDebug( "- OpenGL not recommended on this system" );
  }

#if defined( Q_WS_X11 )
  // check if X render is present:
  QPixmap tmp( 1, 1 );
  if( !tmp.x11PictureHandle() && tmp.paintEngine()->type() == QPaintEngine::X11 ) {
    QxColors::xRenderPresent = false;
    if( QxColors::verbose ) {
      qDebug( "- X render not present" );
    }
  }

#endif

  QWidget w;
  if( QxColors::verbose ) {
    qDebug() << "- Color depth: " << QString::number( w.depth() );
  }
}

void QxColors::postConfigure()
{
  if( !QxColors::noAdapt ) {
    QWidget w;
    if( w.depth() < 16 ) {
      QxColors::useEightBitPalette = true;
      QxColors::adapted = true;
      if( QxColors::verbose ) {
        qDebug() << "- Adapt: Color depth less than 16 bit. Using 8 bit palette";
      }
    }

    if( !QxColors::xRenderPresent ) {
      QxColors::setLowSettings();
      QxColors::adapted = true;
      if( QxColors::verbose ) {
        qDebug() << "- Adapt: X renderer not present. Using low settings";
      }
    }
  }

  if( !QxColors::openGlRendering && !QxColors::softwareRendering ) {
    // The user has not decided rendering system. So we do it instead:
    if( QxColors::openGlAvailable ) {
      QxColors::openGlRendering = true;
    } else {
      QxColors::softwareRendering = true;
    }
  }
}
